/*
Copyright 2010-2011 CumulusCloud
http://cumuluscloud.cc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package appmanager.server;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import appmanager.client.AppService;
import appmanager.server.appstore.AppStore;
import appmanager.server.appstore.runner.InstallRun;
import appmanager.server.appstore.runner.Runner;
import appmanager.server.tools.HashUtilities;
import appmanager.server.tools.ReflectionTools;
import appmanager.server.xmlvo.Application;
import appmanager.server.xmlvo.Description;
import appmanager.shared.vo.LocalApp;
import appmanager.shared.vo.Progress;
import appmanager.shared.vo.RemoteApp;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import cumulusCloud.common.InformationPath;
import cumulusCloud.common.ManageApplication;

@SuppressWarnings("serial")
public class AppServiceImpl extends RemoteServiceServlet implements AppService {
	private static AppStore appStore = AppStore.getInstance();
	private static FilenameFilter warFilter = new FilenameFilter() {
		@Override
		public boolean accept(File dir, String name) {
			return name.endsWith(".war");
		}
	};

	@Override
	public void delete(LocalApp app) throws IllegalArgumentException {
		ManageApplication.deleteApplication(app.getWebname());
	}

	@Override
	public List<LocalApp> getLocalAppList() throws IllegalArgumentException {
		File appdir = new File(InformationPath.getCloudAppsInstallPath());
		List<LocalApp> result = new ArrayList<LocalApp>();
		for (File war : appdir.listFiles(warFilter)) {
			String name = war.getName().substring(0, war.getName().length()-4);
			result.add(new LocalApp(name, HashUtilities.hash(war)));
		}

		return result;
	}

	@Override
	public List<RemoteApp> getLocalUpdateList() throws IllegalArgumentException {
		List<RemoteApp> fullRemoteList = getRemoteAppList();
		List<LocalApp> fullLocalList = getLocalAppList();
		List<RemoteApp> result = new ArrayList<RemoteApp>();
		
		for(LocalApp local : fullLocalList) {
			for (RemoteApp remote : fullRemoteList) {
				// Get the remote object corresponding to the local one
				if (remote.getWebName().equals(local.getWebname())) {
					// Check the hashing
					if (!remote.getSha512().equals(local.getHash())) {
						result.add(remote);
					}
					break;
				}
			}
		}
		
		return result;
	}

	@Override
	public List<Progress> getProgresses() throws IllegalArgumentException {
		return Runner.getProgresses();
	}

	@Override
	public List<RemoteApp> getRemoteAppList() throws IllegalArgumentException {
		List<RemoteApp> result = new ArrayList<RemoteApp>();
		List<Application> applications = appStore.getApplist();
		
		for (Application app: applications) {
			RemoteApp rem = ReflectionTools.cleanObject(app, RemoteApp.class);
			// Add the English description
			String description = "";
			String language = "EN";
			
			for (Description d: app.getDescriptions()) {
				if (language.equals(d.getLanguage())) {
					description = d.getText();
					break;
				}
				
				if (description.isEmpty()) {
					description = d.getText();
				}
			}
			
			rem.setDescription(description);
			
			result.add(rem);
		}
		
		return result;
	}

	@Override
	public void install(RemoteApp app) throws IllegalArgumentException {
		Runner.addRun(new InstallRun(app.getWebName(), app.getSha512()));
		
	}

	@Override
	public void refreshRemoteAppList() throws IllegalArgumentException {
		appStore.updateAppListFile();
	}
}
